# @author: Samuel Taylor <samtaylor.uk@gmail.com>
# @package: winecellar
# @license: GNU GPLv3
#
# -*- coding: utf-8 -*-
#
################################################
# NOTE: Parts have been stolen from Wine-Doors #
################################################
#
# Copyright (C) 2010  Samuel Taylor <samtaylor.uk@gmail.com>
#----------------------------------------------------------------------
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#-----------------------------------------------------------------------
from __future__ import division

__author__ = 'Samuel Taylor <samtaylor.uk@gmail.com>'

import re
import os
import hashlib
import gtk
from WineCellar.Logger import logger
from WineCellar.Config import get_data_file

# Stolen from Wine-Doors
def getCD():
    cdpath = False
    # We should be usin' HAL
    import dbus
    try:
        #import dbus
        bus = dbus.SystemBus()
        hal_obj = bus.get_object( 'org.freedesktop.Hal', '/org/freedesktop/Hal/Manager' )
        hal = dbus.Interface( hal_obj, 'org.freedesktop.Hal.Manager' )
        udis = hal.FindDeviceByCapability ( 'volume.disc' )
        print udis
        for udi in udis: 
            dev_obj = bus.get_object ( 'org.freedesktop.Hal', udi )
            dev = dbus.Interface ( dev_obj, 'org.freedesktop.Hal.Device' )
            print dev
            cdpath = dev.GetProperty ('volume.mount_point')
            logger.debug("dbus cd path: "+cdpath)
            if cdpath: break
    except:
        logger.warning( "Can't use HAL for CD detection" )
        cdpath = False
    # Lifted almost completely out of freevo (thanks dischi ;)
    if not cdpath and os.path.isfile( '/etc/fstab' ):
        re_cd        = re.compile( '^(/dev/cdrom[0-9]*|/dev/[am]?cd[0-9]+[a-z]?)[ \t]+([^ \t]+)[ \t]+', re.I )
        re_cdrec     = re.compile( '^(/dev/cdrecorder[0-9]*)[ \t]+([^ \t]+)[ \t]+', re.I )
        re_dvd       = re.compile( '^(/dev/dvd[0-9]*)[ \t]+([^ \t]+)[ \t]+', re.I )
        re_iso       = re.compile( '^([^ \t]+)[ \t]+([^ \t]+)[ \t]+(iso|cd)9660', re.I )
        re_automount = re.compile( '^none[ \t]+([^ \t]+).*supermount.*dev=([^,]+).*', re.I )
        re_bymountcd = re.compile( '^(/dev/[^ \t]+)[ \t]+([^ ]*cdrom[0-9]*)[ \t]+', re.I )
        re_bymountdvd= re.compile( '^(/dev/[^ \t]+)[ \t]+([^ ]*dvd[0-9]*)[ \t]+', re.I )
        fd_fstab = open( '/etc/fstab' )
        for line in fd_fstab:
            # Match on the devices /dev/cdrom, /dev/dvd, and fstype iso9660
            match_cd        = re_cd.match( line )
            match_cdrec     = re_cdrec.match( line )
            match_dvd       = re_dvd.match( line )
            match_iso       = re_iso.match( line )
            match_automount = re_automount.match( line )
            match_bymountcd = re_bymountcd.match( line )
            match_bymountdvd= re_bymountdvd.match( line )
            mntdir = ''
            if match_cd or match_bymountcd:
                m = match_cd or match_bymountcd
                mntdir = m.group( 2 )
            elif match_cdrec:
                mntdir = match_cdrec.group( 2 )
            elif match_dvd or match_bymountdvd:
                m = match_dvd or match_bymountdvd
                mntdir = m.group( 2 )
            elif match_iso:
                mntdir = match_iso.group( 2 )
            elif match_automount:
                mntdir = match_automount.group( 1 )
            if mntdir:
                cdpath = mntdir
        fd_fstab.close()
    # Some distros like Foresight Linux still use mtab
    if not cdpath and os.path.isfile( "/etc/mtab" ):
        re_cd = re.compile( '^(/dev/[^ ]+)[ ]+(/media/[^/]*)[ ]+udf' )
        for line in open( "/etc/mtab" ):
            match_cd = re_cd.match( line )
            if match_cd:
                mntdir = match_cd.group( 2 )
            if mntdir:
                cdpath = mntdir
    # TODO: add support for Solaris vfstab
#    if not cdpath and os.path.isfile( "/etc/vfstab" ):
#        log.Warn( "Support for Solaris vfstab not implemented yet" ) 
    return cdpath

def md5File(file, block_size=2**20):
    f = open(file, 'r')
    md5 = hashlib.md5()
    while True:
        data = f.read(block_size)
        if not data:
            break
        md5.update(data)
    return hexify(md5.digest())

# Stolen from Wine-Doors
def hexify(s):
    res = ''
    for c in s:
        res += '%02x' % ord(c)
    return res
    
def uniqifyList(seq):
    # Not order preserving
    return {}.fromkeys(seq).keys()


def humanize_bytes(bytes, precision=1):
    """Return a humanized string representation of a number of bytes.

    Assumes `from __future__ import division`.

    >>> humanize_bytes(1)
    '1 byte'
    >>> humanize_bytes(1024)
    '1.0 kB'
    >>> humanize_bytes(1024*123)
    '123.0 kB'
    >>> humanize_bytes(1024*12342)
    '12.1 MB'
    >>> humanize_bytes(1024*12342,2)
    '12.05 MB'
    >>> humanize_bytes(1024*1234,2)
    '1.21 MB'
    >>> humanize_bytes(1024*1234*1111,2)
    '1.31 GB'
    >>> humanize_bytes(1024*1234*1111,1)
    '1.3 GB'
    """
    abbrevs = (
        (1<<50L, 'PB'),
        (1<<40L, 'TB'),
        (1<<30L, 'GB'),
        (1<<20L, 'MB'),
        (1<<10L, 'kB'),
        (1, 'bytes')
    )
    if bytes == 1:
        return '1 byte'
    for factor, suffix in abbrevs:
        if bytes >= factor:
            break
    return '%.*f %s' % (precision, bytes / factor, suffix)
    
def GetInHMS(seconds):
    hours = seconds / 3600
    minutes = seconds / 60
    if hours == 0:
        return "%02d:%02d" % (minutes, seconds)
    return "%02d:%02d:%02d" % (hours, minutes, seconds)


def get_builder(builder_file_name):
    """Return a fully-instantiated gtk.Builder instance from specified ui 
    file
    
    :param builder_file_name: The name of the builder file, without extension.
        Assumed to be in the 'ui' directory under the data path.
    """
    # Look for the ui file that describes the user interface.
    ui_filename = get_data_file('ui', '%s.ui' % (builder_file_name,))
    if not os.path.exists(ui_filename):
        ui_filename = None

    builder = gtk.Builder()
    builder.set_translation_domain('WineCellar')
    builder.add_from_file(ui_filename)
    return builder


# Owais Lone : To get quick access to icons and stuff.
def get_media_file(media_file_name):
    media_filename = get_data_file('media', '%s' % (media_file_name,))
    if not os.path.exists(media_filename):
        media_filename = None

    return "file:///"+media_filename


